<?php

declare(strict_types=1);

namespace So;

use Hyperf\Validation\Request\FormRequest;
use Hyperf\Contract\ValidatorInterface;
use Hyperf\Validation\Contract\ValidatorFactoryInterface as ValidationFactory;
use Hyperf\Di\Annotation\Inject;

/*
 * 实现带场景的验证器基类
 * $scene array 场景
 * @author Saopig <1306222220@qq.com>
 */

class Validation extends FormRequest
{

    /**
     * @Inject
     * @var Request
     */
    protected $request;

    /**
     * 验证场景
     *
     * @var string
     */
    public $scene = [];

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @param ValidationFactory $factory
     * @return ValidatorInterface
     */
    protected function createDefaultValidator(ValidationFactory $factory): ValidatorInterface
    {

        return $factory->make(
            $this->validationData(), $this->getSceneRules(),
            $this->messages(), $this->attributes()
        );
    }

    /**
     * 获取场景验证规则
     *
     * @return array
     */
    public function getSceneRules(string $scene = '')
    {
        return $this->handleScene(call_user_func_array([$this, 'rules'], []), $scene);
    }

    /***
     * 基于路由名称的场景验证
     *
     * @param array $rule
     * @return array
     */
    public function handleScene(array $rule, string $scene = '')
    {
        $scene = empty($scene) ? $this->getSceneName() : $scene;
        $arr = [];
        foreach (($scene = $this->scene[$scene] ?? []) as $item) {
            if (isset($rule[$item])) {
                $arr[$item] = $rule[$item];
            }
        }
        return $arr ?: $rule;
    }

    /**
     * 获取场景名称
     *
     * @return string
     */
    public function getSceneName()
    {
        list($controller, $action) = $this->request->getPath(true);
        return $action;
    }


}
